//
// Created by luolijun on 2021/10/31.
//

#include "DiagramEditorWidget.h"
#include "FacadeItem.h"
#include "src/facade/builtin/FacadeClass.h"

#include "utils/asserts.h"

#include <QDebug>
#include <QMouseEvent>

namespace falcon {

DiagramEditorWidget::DiagramEditorWidget(QWidget* parent)
    : QGraphicsView(parent) {

    falconDocument = nullptr;

    //  创建一个 scene
    QGraphicsScene* ownerScene = new QGraphicsScene(this);

    //  将 scene 设置到本 view
    setScene(ownerScene);

    //  设置背景刷
    setBackgroundBrush(QBrush(QColor::fromRgb(220, 220, 100)));

    //  TODO 后面要删掉：绘制十字交叉线
    ownerScene->addLine(QLineF { 0, -100, 0, +100 });
    ownerScene->addLine(QLineF { -100, 0, +100, 0 });
}

void DiagramEditorWidget::mousePressEvent(QMouseEvent* event) {
    QPointF pos = event->localPos();

    //  如果已经有 pengding 的 Facade，那么表示需要新建一个 Facade
    if (falconDocument->pendingFacade != nullptr) {
        addFacade(falcon::POINT { pos.x(), pos.y() }, falconDocument->pendingFacade->clone());
        falconDocument->pendingFacade = nullptr;
        QGraphicsView::mousePressEvent(event);
        return;
    }

    //  如果按下的位置下有 Facade，表示用户想选中并拖动元素
    QPointF mapPos = mapToScene(event->pos());
    QTransform transform;
    QGraphicsItem* item = scene()->itemAt(mapPos, transform);
    if (item != nullptr) {
        QGraphicsView::mousePressEvent(event);
        return;
    }

    //  如果按下的位置下没有任何 Facade，表示想框选元素
    origin = event->pos();
    if (!rubberBand)
        rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
    rubberBand->setGeometry(QRect(origin, QSize()));
    rubberBand->show();
    QGraphicsView::mousePressEvent(event);
    return;
}

void DiagramEditorWidget::addFacade(falcon::POINT pos, falcon::Facade* f) {
    ASSERT(f != nullptr);

    QGraphicsScene* s = scene();
    ASSERT(s != nullptr);

    //  先构造出窗口对象
    FacadeItem* w = new FacadeItem(f);
    ASSERT(w != nullptr);

    w->setData(0, QVariant::fromValue((void*)f));

    qDebug() << QString("press: %1 %2").arg(pos.x).arg(pos.y);

    QPointF mapPos = mapToScene(mapFromParent(QPointF(pos.x, pos.y).toPoint()));

    qDebug() << QString("maped: %1 %2").arg(mapPos.x()).arg(mapPos.y());

    //  设置位置
    w->move(falcon::POINT(mapPos.x(), mapPos.y()));

    //  加入到场景对象
    s->addItem(w);

    qDebug() << QString("childs-count: %1").arg(children().size());
}

void DiagramEditorWidget::delFacade(Facade* f) {
}

void DiagramEditorWidget::attach(FalconDocument* doc, Package* pkg, Diagram* dag) {
    falconDocument = doc;
    package = pkg;
    diagram = dag;
}

void DiagramEditorWidget::mouseMoveEvent(QMouseEvent* event) {
    rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}

void DiagramEditorWidget::mouseReleaseEvent(QMouseEvent* event) {
    rubberBand->hide();
    // determine selection, for example using QRect::intersects()
    // and QRect::contains().
}

} // namespace falcon